package Semant;

import Symbol.Symbol;
import Symbol.Table;
import Types.INT;
import Types.RECORD;
import Types.STRING;
import Types.Type;
import Types.VOID;

public class Env {
	Table venv;
	Table tenv;
	//Table loopenv;
	ErrorMsg.ErrorMsg errorMsg;
	Env(ErrorMsg.ErrorMsg err){
		errorMsg=err;
		//initialize venv and tenv with predefined identifiers
		venv = new Table();
		tenv = new Table();
		//loopenv = new Table();
		
		tenv.put(Symbol.symbol("int"), new Types.INT());
		tenv.put(Symbol.symbol("string"),new Types.STRING());
		
		Symbol name = null;
		RECORD formals = null;
		Type result = null;
		
		/* System Utility function declarations */
		name = Symbol.symbol("print");
		formals = new RECORD(Symbol.symbol("s"), new STRING(), null);
		result = new VOID();
		addFunction(name, formals, result);
		
		name = Symbol.symbol("printi");
		formals = new RECORD(Symbol.symbol("i"), new INT(), null);
		result = new VOID();
		addFunction(name, formals, result);
		
		name = Symbol.symbol("flush");
		formals = null;
		result = new VOID();
		addFunction(name, formals, result);
		
		name = Symbol.symbol("getchar");
		formals = null;
		result = new STRING();
		addFunction(name, formals, result);
		
		name = Symbol.symbol("ord");
		formals = new RECORD(Symbol.symbol("s"), new STRING(), null);
		result = new INT();
		addFunction(name, formals, result);
		
		name = Symbol.symbol("chr");
		formals = new RECORD(Symbol.symbol("i"), new INT(), null);
		result = new STRING();
		addFunction(name, formals, result);
		
		name = Symbol.symbol("size");
		formals = new RECORD(Symbol.symbol("s"), new STRING(), null);
		result = new INT();
		addFunction(name, formals, result);
		
		name = Symbol.symbol("substring");
		formals = new RECORD(Symbol.symbol("s"), new STRING(), new RECORD(
			Symbol.symbol("f"), new INT(), new RECORD(Symbol.symbol("n"),
			new INT(), null)));
		result = new STRING();
		addFunction(name, formals, result);
		
		name = Symbol.symbol("concat");
		formals = new RECORD(Symbol.symbol("s1"), new STRING(), new RECORD(
			Symbol.symbol("s2"), new STRING(), null));
		result = new STRING();
		addFunction(name, formals, result);
		
		name = Symbol.symbol("not");
		formals = new RECORD(Symbol.symbol("i"), new INT(), null);
		result = new INT();
		addFunction(name, formals, result);
		
		name = Symbol.symbol("exit");
		formals = new RECORD(Symbol.symbol("i"), new INT(), null);
		result = new VOID();
		addFunction(name, formals, result);
	}
	private void addFunction(Symbol name, RECORD formals, Type result)
	{
		//Level level = new Level(root, name, new BoolList(true, null));
		FunEntry func = new FunEntry(formals, result);
		venv.put(name, func);
	}

}
